///////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2009 Summit Contributors.  
// See: http://code.google.com/p/tyemill/wiki/SummitContributors
//
// The name and logo of Summit are trademarks of TYEMILL, LLC - All Rights 
// Reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a 
// copy of this software and associated documentation files (the "Software"), 
// to deal in the Software without restriction, including without 
// limitation the rights to use, copy, modify, merge, publish, distribute, 
// sublicense, and/or sell copies of the Software, and to permit persons to 
// whom the Software is furnished to do so, subject to the following 
// conditions:
//
// The above copyright notice and this permission notice shall be included 
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////////////////////////////////////////

package org.tyemill.utils
{
import flash.errors.IllegalOperationError;

/** A base for classes that are to work as Enums.
 * 
 * <p>Enables easy id conversions and a check for values in an expected
 * range.</p> **/ 	
public class EnumBase
{
	/** @private **/
	private var _validValueNames:Object; 	// Hash by name
	private var _validValueIndices:Object; 	// Hash by index
	private var _counter:int; 				// The count of known values
	
	/** Constructor. **/
	public function EnumBase()
	{
		if(!_validValueNames) 
		{
			_validValueNames = new Object();
			_validValueIndices = new Object();
			_counter = 0;
		}
	}
	
	/** Adds a value to internal hashs.
	 * @param validName 
	 * The name of the valid value.**/
	protected function addValue(validName:String):String
	{
		try
		{
			_validValueNames[validName] = _counter;
			_validValueIndices[_counter] = validName;
		}
		catch(e:Error)
		{
			new EnumBase();
			return addValue(validName);
		}
		
		_counter += 1;
		
		return validName;
	}
	
	/** Gets the id of a known value. <p>Returns -1 if the value is not known.
	 * If defined debug builds, throws an <code>IllegalOperationError</code>
	 * in the event of an unknown value.</p>
	 * @param value
	 * The value to get the id for. **/
	public function valueToId(value:String):int
	{
		var result:int = -1;
			
		try
		{
			if(_validValueNames.hasOwnProperty(value))
			{
				result =  _validValueNames[value];
			}
		}
		catch(e:Error)
		{
			new EnumBase();
			return valueToId(value);
		}
		
		CONFIG::debugging 
		{
			if(result == -1) 
			{
				throw new IllegalOperationError("Unknown operationName: " +
				value);
			}
		}
		
		return result;
	}
	
	/** Gets the name of a known value from an id. <p>Returns <code>null</code>
	 * if the id is unknown and throws an <code>IllegalOperationError</code>
	 * in defined debug builds in the unknown id case.</p> **/
	public function idToValue(id:int):String
	{
		var value:String = null;
		
		try
		{
			if(_validValueIndices.hasOwnProperty(id))
				value = _validValueIndices[id];
		}
		catch(e:Error)
		{
			new EnumBase();
			return idToValue(id);	
		}
		
		CONFIG::debugging 
		{
			if(null == value) 
			{
				throw new IllegalOperationError("Unknown id: " + id);
			}
		}
		
		return value;
	}
// example useage
// public static const THING:String 		= addValue("thing");	
}
}
//////////////////////////////////////////////////////// gmarius@tyemill.com //